package android.project;

import java.io.File;
import java.util.regex.Pattern;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class AndroidProjectIndividualImageActivity extends Activity implements OnClickListener
{
	private enum RenameError
	{
		Default,
		FileAlreadyExists,
		FileNameContainDots
	}
	
	private static final String FOLDER_NAME = "/androidProjectDir/";
	
	// Fields
	private String m_fileName = null;
	private ImageView m_imageView = null;
	private Bitmap m_bitmap = null;
	private TextView m_instructions, m_confirmation;
	private Button m_renameButton, m_deleteButton, m_keepButton;
	private EditText m_newNameView;
	
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle a_savedInstanceState) 
	{
	    super.onCreate(a_savedInstanceState);
	    setContentView(R.layout.individual_image);
	    
	    m_imageView = (ImageView)findViewById(R.id.individual_imageView_image);
	    
	    PersistantImage persistantImage = (PersistantImage)getLastNonConfigurationInstance();
	    
	    if (persistantImage == null)
	    {
		    Bundle extras = getIntent().getExtras();
		    
		    m_fileName = extras.getString("fileName");
		    
		    Log.d("debug-event", "FileName: " + m_fileName);
		    
		    if (m_fileName != null)
		    {
		    	new LoadImage().execute();
		    }
	    }
	    else
	    {
	    	m_fileName = persistantImage.FileName;
	    	m_bitmap = persistantImage.Image;
	    	m_imageView.setImageBitmap(m_bitmap);
	    }
	}
	
	public void onClick(View a_v) 
	{
		switch(a_v.getId())
		{
			case R.id.individual_button_rename :
				Log.d("debug-event", "Button clicked try to rename the file.");
				// Rename the file.
				new RenameImage().execute();
			break;
			case R.id.individual_button_deleteButton :
				Log.d("debug-event", "Button clicked, user confirmed that file should be deleted.");
				// Delete the file.
				new DeleteImage().execute();
				break;
			case R.id.individual_button_keepButton : 
				Log.d("debug-event", "User wanted to keep the file.");
				// Reset the view to the normal view of the current image.
				setContentView(R.layout.individual_image);
				m_imageView = (ImageView)findViewById(R.id.individual_imageView_image);				
				m_imageView.setImageBitmap(m_bitmap);	
				break;
		}
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu a_menu) 
	{
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.menu_individual, a_menu);
		return true;
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem a_item) 
	{
		switch(a_item.getItemId())
		{
			case R.id.individual_item_delete :
				Log.d("debug-event", "Should change view so user can delete the image.");
				
				// Set the view to the one handling removal of files.
				setContentView(R.layout.individual_delete);
				m_confirmation = (TextView)findViewById(R.id.individual_textView_confirmation);
				
				// Set the text for the confirmation.
				String confirmation = "You are about to delete the image:\n" + m_fileName + "\nAre you sure you want " +
						"to delete this image? Deleting an image permanent and you can't recover a deleted images. Upon successful " + 
						"delete you will be returned to the image-list. Please refresh your image-list before continuing to view other images.";
				m_confirmation.setText(confirmation);
				
				// Set the onClick for the buttons.
				m_deleteButton = (Button)findViewById(R.id.individual_button_deleteButton);
				m_keepButton = (Button)findViewById(R.id.individual_button_keepButton);
				
				m_deleteButton.setOnClickListener(this);
				m_keepButton.setOnClickListener(this);
				break;
			case R.id.individual_item_rename :
				Log.d("debug-event", "Should change view so that user can rename the image.");
				
				// Set the view to the one handling renaming of files.
				setContentView(R.layout.individual_rename);
			    m_instructions = (TextView)findViewById(R.id.individual_textView_instructions);
				
				// Set the text for the instructions.
				String instructions = "You are about to rename the image:\n" + m_fileName + "\nPlease input the new name WITHOUT a file ending. Remember that the " + 
				"rename is final. If you want the old name back you will have to rename the image again. Note that the rename may not be reflected in the image list " + 
				"untill after you reload the list.";
				m_instructions.setText(instructions);
				
				// Set the onClick for the button.
				m_renameButton = (Button)findViewById(R.id.individual_button_rename);
				m_renameButton.setOnClickListener(this);
				
				m_newNameView = (EditText)findViewById(R.id.individual_editText_newFileName);
				
				break;
		}
		return true;
	}
	
	private void Finish()
	{
		finish();
	}
	
	@Override
	public Object onRetainNonConfigurationInstance() 
	{
		PersistantImage persistant = new PersistantImage(m_bitmap, m_fileName);
		return persistant;
	}

	private class DeleteImage extends AsyncTask<Void, Void, Boolean>
	{
		@Override
		protected Boolean doInBackground(Void... params) 
		{
			boolean wasFileDeleted = false;
			File fileToBeDeleted = new File(Environment.getExternalStorageDirectory() + FOLDER_NAME + m_fileName);
			
			if (fileToBeDeleted.isFile() == true)
			{
				try
				{
					wasFileDeleted = fileToBeDeleted.delete();
				}
				catch (Exception e)
				{
					e.printStackTrace();
					Log.d("debug-event", "Error: " + e.toString());
				}
			}
			else
			{
				// Something went wrong.
				Log.d("debug-event", "Filename was not a file");
			}
			
			return wasFileDeleted;
		}
		
		@Override
		protected void onPostExecute(Boolean a_wasFileDeleted) 
		{
			if (a_wasFileDeleted == true)
			{
				// File was deleted.
				Log.d("debug-event", "Was file deleted: " + a_wasFileDeleted);
				Finish();
			}
			else
			{
				// File was NOT deleted, something went wrong.
				Log.d("debug-event", "Was file deleted: " + a_wasFileDeleted);
			}
		}
		
	}
	
	private class RenameImage extends AsyncTask<Void, Void, Boolean>
	{		
		// Fields.
		private String m_newName = "";
		private RenameError m_renameError = RenameError.Default;
		
		@Override
		protected Boolean doInBackground(Void... params) 
		{
			boolean ret = false;
			
			// See if the new fileName is fine to use.
			m_newName = m_newNameView.getEditableText().toString();
			
			// Check if the file follows the preset naming convention.
			if (isNewNameValid(m_newName, m_fileName) == true)
			{
				// Add the file ending and create the file object.
				m_newName = m_newName + ".png";
				File newFileName = new File(Environment.getExternalStorageDirectory() + FOLDER_NAME + m_newName);
				
				// Get the old file.
				File oldFile = new File(Environment.getExternalStorageDirectory() + FOLDER_NAME + m_fileName);
				
				// Check if there already exists a file with that name.
				if (newFileName.isFile() == false)
				{
					// Rename the file.
					try
					{
						oldFile.renameTo(newFileName);
					}
					catch (Exception e)
					{
						e.printStackTrace();
						Log.d("debug-event", "Error: " + e.toString());
					}
				}
				else
				{
					// File already exists with this name, give error.
					Log.d("debug-event", "A file with this name already exists.");
					m_renameError = RenameError.FileAlreadyExists;
				}
				
				// Check if rename was successful if so return true otherwise return false.
				if (newFileName.isFile() == true && oldFile.isFile() == false)
				{
					ret = true;
				}
			}
			return ret;
		}
		
		@Override
		protected void onPostExecute(Boolean a_wasFileRenamed) 
		{
			if (a_wasFileRenamed == true)
			{
				// Set it back to the normal view, also set the old fileName to the new name.
				setContentView(R.layout.individual_image);
				m_fileName = m_newName;
				Log.d("debug-event", "File was renamed to: " + m_fileName);
				m_imageView = (ImageView)findViewById(R.id.individual_imageView_image);				
				m_imageView.setImageBitmap(m_bitmap);
				Toast.makeText(getApplicationContext(), "File was renamed successfully!", Toast.LENGTH_SHORT).show();
			}
			else
			{
				// Some error occured.
				Log.d("debug-event", "Was file renamed: " + a_wasFileRenamed);
				Log.d("debug-event", "Error: " + m_renameError.toString());
				switch (m_renameError) 
				{
					case FileAlreadyExists :
						Toast.makeText(getApplicationContext(), "A file with this name already exits.", Toast.LENGTH_SHORT).show();
						break;
					case FileNameContainDots :
						Toast.makeText(getApplicationContext(), "The new file name must not contain dots.", Toast.LENGTH_SHORT).show();
						break;
				}
			}
		}
		
		private boolean isNewNameValid(String a_filename, String a_oldFileName)
		{
			// Check for file ending.
			Pattern dotPattern = Pattern.compile("[.]");
			
			// Split to see if the name contained a dot. If it did user probably tried to input a file ending.
			String[] splitArray = dotPattern.split(a_filename);
			
			if (splitArray.length > 1)
			{
				// File name contained dot return false.
				m_renameError = RenameError.FileNameContainDots;
				return false;
			}
			
			// Check if the user input the same name but with Capital letters instead of small ones and the other way around.
			if (a_filename.equalsIgnoreCase(a_oldFileName) == true)
			{
				// The file names were the same, give error and return false.
				m_renameError = RenameError.FileAlreadyExists;		
				return false;
			}
			
			
			// Check if user input anything other than the selected characters.
			
			return true;
		}
		
	}
	
	private class LoadImage extends AsyncTask<Void, Void, Bitmap>
	{
		@Override
		protected Bitmap doInBackground(Void... a_params) 
		{
			Bitmap image = null;
			
			File imageFile = new File(Environment.getExternalStorageDirectory() + FOLDER_NAME + m_fileName);
			if (imageFile.isFile() == true)
			{
				Log.d("debug-event", "Absolute filePath: " + imageFile.getAbsolutePath());
				try
				{
					image = BitmapFactory.decodeFile(imageFile.getAbsolutePath());
				}
				catch (Exception e)
				{
					e.printStackTrace();
					Log.d("debug-event", "Error: " + e.toString());
				}
				

			}
			return image;
		}
		
		@Override
		protected void onPostExecute(Bitmap a_image) 
		{
			if (a_image != null)
			{
				try
				{
					m_imageView.setImageBitmap(a_image);
					m_bitmap = a_image;
				}
				catch(Exception e)
				{
					e.printStackTrace();
					Log.d("debug-event", "Error: " + e.toString());
				}
			}
		}
	}
}
